﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;

namespace POVRay {
    public class Scene {
        public static String IndentOneLevel { get { return "    "; } }
        public static bool GlobalOneLiners { get; set; }
        public static String Indentation(int level) {
            if (GlobalOneLiners) {
                return "";
            } else {
                StringBuilder sb = new StringBuilder(Environment.NewLine);
                for (int i = 0; i < level; ++i) {
                    sb.Append(IndentOneLevel);
                }
                return sb.ToString();
            }
        }

        LinkedList<String> includes = new LinkedList<string>();

        public String FilePath { get; protected set; }
        public GlobalSettings GlobalSettings { get; set; }
        public Color? Background { get; set; }
        public SkySphere SkySphere { get; set; }
        public Camera Camera { get; set; }
        public LinkedList<Fog> Fogs { get; protected set; }
        public LinkedList<Rainbow> Rainbows { get; protected set; }
        //TODO: media
        public LinkedList<LightSource> LightSources { get; protected set; }
        public LinkedList<Object> Objects { get; set; }
        
        public Scene(String filePath) {
            FilePath = filePath;

            if (!FilePath.EndsWith(".pov")) {
                FilePath += ".pov";
            }

            Fogs = new LinkedList<Fog>();
            Rainbows = new LinkedList<Rainbow>();
            LightSources = new LinkedList<LightSource>();
            Objects = new LinkedList<Object>();

            /*
            includes.AddLast("colors");
            includes.AddLast("textures");
            includes.AddLast("shapes");
            includes.AddLast("metals");
            includes.AddLast("glass");
            includes.AddLast("woods");
             */
        }

        protected void WriteLine(TextWriter tw, String text) {
            tw.WriteLine(text);
        }

        public void WriteToFile() {
            TextWriter tw = new StreamWriter(FilePath, false);

            foreach(String include in includes) {
                WriteLine(tw, "#include \"" + include + ".inc\"");
            }

            if (GlobalSettings != null) {
                WriteLine(tw, "");
                WriteLine(tw, GlobalSettings.ToString(0));
            }

            if (Background.HasValue) {
                WriteLine(tw, "");
                WriteLine(tw, "background { " + Scene.Indentation(1) + Background.Value.ToString());
                WriteLine(tw, "}");
            }

            if (SkySphere != null) {
                WriteLine(tw, "");
                WriteLine(tw, SkySphere.ToString(0));
            }

            foreach (Fog fog in Fogs) {
                WriteLine(tw, "");
                WriteLine(tw, fog.ToString(0));
            }

            foreach (Rainbow rainbow in Rainbows) {
                WriteLine(tw, "");
                WriteLine(tw, rainbow.ToString(0));
            }

            if (Camera != null) {
                WriteLine(tw, "");
                WriteLine(tw, Camera.ToString(0));
            }

            WriteLine(tw, "");
            WriteLine(tw, "//light sources");
            WriteLine(tw, "");

            foreach (LightSource lightSource in LightSources) {
                WriteLine(tw, lightSource.ToString(0));
                WriteLine(tw, "");
            }

            WriteLine(tw, "");
            WriteLine(tw, "//objects");
            WriteLine(tw, "");

            foreach (Object obj in Objects) {
                WriteLine(tw, obj.ToString(0));
                WriteLine(tw, "");
            }

            tw.Close();
        }

        public void Render(String executablePath) {
            Process p = new Process();
            p.StartInfo.FileName = executablePath;
            p.StartInfo.Arguments = "/RENDER \"" + FilePath + "\"";
            p.Start();
        }
    }
}
